package com.qianfeng.es.service;


//
//                            _ooOoo_  
//                           o8888888o  
//                           88" . "88  
//                           (| -_- |)  
//                            O\ = /O  
//                        ____/`---'\____  
//                      .   ' \\| |// `.  
//                       / \\||| : |||// \  
//                     / _||||| -:- |||||- \  
//                       | | \\\ - /// | |  
//                     | \_| ''\---/'' | |  
//                      \ .-\__ `-` ___/-. /  
//                   ___`. .' /--.--\ `. . __  
//                ."" '< `.___\_<|>_/___.' >'"".  
//               | | : `- \`.;`\ _ /`;.`/ - ` : | |  
//                 \ \ `-. \_ __\ /__ _/ .-` / /  
//         ======`-.____`-.___\_____/___.-`____.-'======  
//                            `=---='  
//  
//         .............................................  
//                  佛祖镇楼            BUG辟易  
//          佛曰:  
//                  写字楼里写字间，写字间里程序员；  
//                  程序人员写程序，又拿程序换酒钱。  
//                  酒醒只在网上坐，酒醉还来网下眠；  
//                  酒醉酒醒日复日，网上网下年复年。  
//                  但愿老死电脑间，不愿鞠躬老板前；  
//                  奔驰宝马贵者趣，公交自行程序员。  
//                  别人笑我忒疯癫，我笑自己命太贱；  


import com.qianfeng.es.utils.ESClient;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchScrollRequest;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.Operator;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.reindex.BulkByScrollResponse;
import org.elasticsearch.index.reindex.DeleteByQueryRequest;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;

import java.io.IOException;

/**
 * Created by jackiechan on 2021/11/15 10:29
 *
 * @author jackiechan
 * @version 1.0
 * //TODO 给最美丽的芳姐介绍学生
 * @since 1.0
 */

public class DocService {
    private static final String INDEX_NAME = "sms-logs-index";//库名

    public void addDoc() throws IOException {
        RestHighLevelClient restHighLevelClient = ESClient.getClient();//获取连接
        IndexRequest indexRequest = new IndexRequest(INDEX_NAME).id("2");//指定主键
        String json = "{\n" +
                "  \"corpName\":\"盒马鲜生1\",\n" +
                "  \"mobile\":\"13100000000\",\n" +
                "  \"createDate\":\"2020-02-18 19:19:20\",\n" +
                "  \"sendDate\":\"2020-02-18 19:19:21\",\n" +
                "  \"longCode\":\"10660000988\",\n" +
                "  \"smsContent\":\"【盒马1】您尾号12345678的订单已开始配送，请在您指定的时间收货不要走开哦~配送员：刘三，电话：13800000000\",\n" +
                "  \"state\":0,\n" +
                "  \"province\":\"北京\",\n" +
                "  \"operatorId\":2,\n" +
                "  \"ipAddr\":\"10.126.2.9\",\n" +
                "  \"replyTotal\":15,\n" +
                "  \"fee\":5\n" +
                "}";
        indexRequest.source(json, XContentType.JSON);//传递数据
        IndexResponse response = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
        System.err.println(response);
    }


    public void addDocNoId() throws IOException {
        RestHighLevelClient restHighLevelClient = ESClient.getClient();//获取连接
        IndexRequest indexRequest = new IndexRequest(INDEX_NAME);//自动生成主键
        String json = "{\n" +
                "  \"corpName\":\"盒马鲜生\",\n" +
                "  \"mobile\":\"13100000000\",\n" +
                "  \"createDate\":\"2020-02-18 19:19:20\",\n" +
                "  \"sendDate\":\"2020-02-18 19:19:21\",\n" +
                "  \"longCode\":\"10660000988\",\n" +
                "  \"smsContent\":\"【盒马】您尾号12345678的订单已开始配送，请在您指定的时间收货不要走开哦~配送员：刘三，电话：13800000000\",\n" +
                "  \"state\":0,\n" +
                "  \"province\":\"北京\",\n" +
                "  \"operatorId\":2,\n" +
                "  \"ipAddr\":\"10.126.2.9\",\n" +
                "  \"replyTotal\":15,\n" +
                "  \"fee\":5\n" +
                "}";
        indexRequest.source(json, XContentType.JSON);//传递数据
        IndexResponse response = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
        System.err.println(response);
    }


    public void updateDoc() throws IOException {
        RestHighLevelClient restHighLevelClient = ESClient.getClient();//获取连接
        String json = "{\n" +
                "  \"corpName\":\"盒马鲜生2222222\"\n" +
                "}";
        UpdateRequest request = new UpdateRequest(INDEX_NAME, "2").doc(json, XContentType.JSON);

        UpdateResponse response = restHighLevelClient.update(request, RequestOptions.DEFAULT);
        System.err.println(response);
    }

    public void deleteDoc() throws IOException {
        RestHighLevelClient restHighLevelClient = ESClient.getClient();//获取连接
        DeleteRequest deleteRequest = new DeleteRequest(INDEX_NAME, "2");
        DeleteResponse response = restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
        System.err.println(response);
    }


    public void termQuery(String field, String value) throws IOException {
//        RestHighLevelClient restHighLevelClient = ESClient.getClient();//获取连接
//        SearchRequest request = new SearchRequest(INDEX_NAME);//设置查询什么库
//        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//        sourceBuilder.query(QueryBuilders.termQuery(field, value));//设置查询的方式为 term 查询
//        request.source(sourceBuilder);//给请求设置查询的 builder
//        SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
//        System.err.println(response);
        processSearch(QueryBuilders.termQuery(field, value));
    }


    public void termsQuery(String field, String... value) throws IOException {
//        RestHighLevelClient restHighLevelClient = ESClient.getClient();//获取连接
//        SearchRequest request = new SearchRequest(INDEX_NAME);//设置查询什么库
//        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//        sourceBuilder.query(QueryBuilders.termsQuery(field,value));//设置查询的方式为 term 查询
//        request.source(sourceBuilder);//给请求设置查询的 builder
//        SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
//        System.err.println(response);
        processSearch(QueryBuilders.termsQuery(field, value));
    }


    public SearchResponse processSearch(QueryBuilder builder) throws IOException {
        RestHighLevelClient restHighLevelClient = ESClient.getClient();//获取连接
        SearchRequest request = new SearchRequest(INDEX_NAME);//设置查询什么库
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(builder);//设置查询的方式为 term 查询
        request.source(sourceBuilder);//给请求设置查询的 builder
        SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
        System.err.println(response);
        return response;
    }


    public void matchAll() throws IOException {
        processSearch(QueryBuilders.matchAllQuery());
    }

    public void match(String field, String value) throws IOException {
        processSearch(QueryBuilders.matchQuery(field, value));
    }

    public void bool_match(String field, String value, Operator operator) throws IOException {
        processSearch(QueryBuilders.matchQuery(field, value).operator(operator));
    }


    public void mult_match(String value, String... field) throws IOException {
        processSearch(QueryBuilders.multiMatchQuery(value, field));
    }


    public void idsQuery(String... id) throws IOException {
        processSearch(QueryBuilders.idsQuery().addIds(id));
    }


    public void prifxQuery(String field, String value) throws IOException {
        processSearch(QueryBuilders.prefixQuery(field, value));
    }

    public void fuzzyQuery(String field, String value) throws IOException {
        processSearch(QueryBuilders.fuzzyQuery(field, value).prefixLength(2));
    }

    public void wildcardQuery(String field, String value) throws IOException {
        processSearch(QueryBuilders.wildcardQuery(field, value));
    }

    public void rangeQuery(String field, String value) throws IOException {
        processSearch(QueryBuilders.rangeQuery(field).gte(5));
    }

    public void regexpQuery(String field, String value) throws IOException {
        processSearch(QueryBuilders.regexpQuery(field, value));
    }

    public void scrollQuery(String field, String value) throws IOException {
        RestHighLevelClient restHighLevelClient = ESClient.getClient();//获取连接

        SearchRequest searchRequest = new SearchRequest(INDEX_NAME);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.matchAllQuery());
        searchRequest.scroll("1m");
        SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        String scrollId = response.getScrollId();


        while (true) {

            SearchScrollRequest searchScrollRequest = new SearchScrollRequest(scrollId);
            SearchResponse searchResponse = restHighLevelClient.scroll(searchScrollRequest, RequestOptions.DEFAULT);
            if (searchResponse.getHits().getHits().length == 0) {
                //没有了
                return;
            }
        }
    }

    public void deleteByQuery() throws IOException {
        RestHighLevelClient restHighLevelClient = ESClient.getClient();//获取连接
        DeleteByQueryRequest deleteByQueryRequest = new DeleteByQueryRequest(INDEX_NAME).setQuery(QueryBuilders.matchAllQuery());
        BulkByScrollResponse response = restHighLevelClient.deleteByQuery(deleteByQueryRequest, RequestOptions.DEFAULT);
    }


    public void boolQuery() throws IOException {
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery()
                .mustNot(QueryBuilders.termQuery("operatorId", 2))
                .must(QueryBuilders.matchQuery("smsContent", "中国"))
                .must(QueryBuilders.matchQuery("smsContent", "平安"))
                .should(QueryBuilders.termQuery("province", "北京"))
                .should(QueryBuilders.termQuery("province", "武汉"));
        processSearch(queryBuilder);
    }


    public void boostingQuery() throws IOException {
        processSearch(QueryBuilders.boostingQuery(
                        QueryBuilders.matchQuery("smsContent", "收货安装"),//查询的基本条件
                        QueryBuilders.matchQuery("smsContent", "王五"))//查询的额外条件,符合这个条件的分数会下降
                .negativeBoost(0.5f));

    }


    public SearchResponse highLightQuery() throws IOException {
        RestHighLevelClient restHighLevelClient = ESClient.getClient();//获取连接
        SearchRequest request = new SearchRequest(INDEX_NAME);//设置查询什么库
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(QueryBuilders.matchQuery("smsContent","安装"));
        HighlightBuilder highlightBuilder=new HighlightBuilder();//高亮的设置
        highlightBuilder.field("smsContent",0);//设置哪个返回的内容中哪个字段高亮
        highlightBuilder.preTags("<font color='red'>");//设置内容要用什么东西高亮,其实就是一段 html 标签
        highlightBuilder.postTags("</font>");//后置标签
        sourceBuilder.highlighter(highlightBuilder);
        request.source(sourceBuilder);//给请求设置查询的 builder
        SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
        System.err.println(response);
        return response;
    }


    public SearchResponse agg(AggregationBuilder builder) throws IOException {
        RestHighLevelClient restHighLevelClient = ESClient.getClient();//获取连接
        SearchRequest request = new SearchRequest(INDEX_NAME);//设置查询什么库
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        ///设置聚合函数
        sourceBuilder.aggregation(builder);
        request.source(sourceBuilder);//给请求设置查询的 builder
        SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
        System.err.println(response);
        return response;
    }
}


